using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Omniture.Studio.EventArgs;

namespace Omniture.Studio.UserControls
{
  public partial class PickList : UserControl
	{
		#region Class Members

		private bool List1Highlighted = true;

		#endregion

		#region Constructors

		public PickList()
		{
			InitializeComponent();
			this.EnableButtons();
			this.listBox1.DrawMode = DrawMode.OwnerDrawFixed;
			this.listBox1.DrawItem += new DrawItemEventHandler(listBox_DrawItem);
			this.listBox2.DrawMode = DrawMode.OwnerDrawFixed;
			this.listBox2.DrawItem += new DrawItemEventHandler(listBox_DrawItem);
		}

		private void listBox_DrawItem(object sender, DrawItemEventArgs e)
		{
			if (e.Index == -1) return;
			ListBox lb = (ListBox)sender;
			DrawingItemEventArgs eventParam = new DrawingItemEventArgs(lb.Items[e.Index]);
			this.OnDrawingItem(eventParam);

			e.DrawBackground();
			Brush textBrush = new SolidBrush(e.ForeColor);
			Font drawFont = e.Font;

			if (eventParam.Hilite)
			{
				drawFont = new Font(drawFont.FontFamily, drawFont.Size, FontStyle.Bold);
			}
			else if ((e.State & DrawItemState.Selected) > 0)
			{
				textBrush = SystemBrushes.HighlightText;
			}
			e.Graphics.DrawString(((ListBox)sender).Items[e.Index].ToString(), drawFont, textBrush, e.Bounds);
		}

		#endregion

		#region Methods

		public override void Refresh()
		{
			base.Refresh();
			this.EnableButtons();

			for (int ii = 0; ii < listBox1.Items.Count; ii++)
				listBox1.Items[ii] = listBox1.Items[ii];
			for (int ii = 0; ii < listBox2.Items.Count; ii++)
				listBox2.Items[ii] = listBox2.Items[ii];

		}

		#endregion

		#region Events

		public event EventHandler<ObjectEventArgs> ItemSelected;
    public event EventHandler<ObjectEventArgs> ItemDeselected;
		public event EventHandler<ObjectEventArgs> ItemHighlighted;
		public event EventHandler<ObjectListEventArgs> SelectAll;
		public event EventHandler<ObjectListEventArgs> DeselectAll;
		public event EventHandler<DrawingItemEventArgs> DrawingItem;

		protected virtual void OnDrawingItem(DrawingItemEventArgs e)
		{
			if (this.DrawingItem != null)
			{
				this.DrawingItem(this, e);
			}
		}

    protected virtual void OnItemSelected(ObjectEventArgs e)
    {
      if(this.ItemSelected != null)
        this.ItemSelected(this, e);
    }

    protected virtual void OnItemDeselected(ObjectEventArgs e)
    {
      if(this.ItemDeselected != null)
        this.ItemDeselected(this, e);
    }

		protected virtual void OnItemHighlighted(ObjectEventArgs e)
		{
			if (this.ItemHighlighted != null)
				this.ItemHighlighted(this, e);
		}

		protected virtual void OnSelectAll(ObjectListEventArgs e)
		{
			if (this.SelectAll != null)
				this.SelectAll(this, e);
		}

		protected virtual void OnDeselectAll(ObjectListEventArgs e)
		{
			if (this.DeselectAll != null)
				this.DeselectAll(this, e);
		}

		protected override void OnResize(System.EventArgs e)
    {
      base.OnResize(e);

      int listWidth = (this.ClientRectangle.Width - pnlMiddle.Width) / 2;
      listBox1.Width = listWidth;
    }

		#endregion

		#region Property Implementations

		public List<object> HighlightedItems
		{
			get
			{
				List<object> retval = new List<object>();
				if (this.List1Highlighted)
				{
					foreach (object o in this.listBox1.SelectedItems)
					{
						retval.Add(o);
					}
				}
				else
				{
					foreach (object o in this.listBox2.SelectedItems)
					{
						retval.Add(o);
					}
				}
				return retval;
			}
			//set
			//{
			//  foreach (object o1 in value)
			//  {
			//    foreach (object o2 in this.listBox1.Items)
			//    {
			//      if (o1 == o2)
			//        this.listBox1.SelectedItems.Add(o2);

			//    }

			//    foreach (object o2 in this.listBox2.Items)
			//    {
			//      if (o1 == o2)
			//        this.listBox2.SelectedItems.Add(o2);

			//    }
				
			//  }
			//}
		}

    public ListBox.ObjectCollection SelectedItems
    {
      get { return this.listBox2.Items; }
    }

    public ListBox.ObjectCollection UnSelectedItems
    {
      get { return this.listBox1.Items; }
		}

		private void EnableButtons()
		{
			cmdSelectAll.Enabled = (listBox1.Items.Count > 0);
			cmdSelectOne.Enabled = (listBox1.SelectedItems.Count > 0);

			cmdDeselectAll.Enabled = (listBox2.Items.Count > 0);
			cmdDeselectOne.Enabled = (listBox2.SelectedItems.Count > 0);
		}

		#endregion

		#region Event Handlers

		private void cmdSelectAll_Click(object sender, System.EventArgs e)
    {
			try
			{
				List<object> list = new List<object>();
				foreach (object o in listBox1.Items)
					list.Add(o);

				listBox2.Items.AddRange(listBox1.Items);
				listBox1.Items.Clear();

				this.EnableButtons();

				//foreach (object o in listBox2.Items)
				//  this.OnItemSelected(new ObjectEventArgs(o));

				this.OnSelectAll(new ObjectListEventArgs(list));

			}
			catch (Exception ex)
			{
				throw;
			}
    }

    private void cmdSelectOne_Click(object sender, System.EventArgs e)
    {
      try
      {
        List<object> oList = new List<object>();
        foreach(object o in listBox1.SelectedItems)
        {
          oList.Add(o);
          listBox2.Items.Add(o);
        }

        for(int ii = listBox1.SelectedItems.Count - 1 ; ii >= 0 ; ii--)
          listBox1.Items.Remove(listBox1.SelectedItems[ii]);

        this.EnableButtons();

				foreach(object o in oList)
				  this.OnItemSelected(new ObjectEventArgs(o));

      }
      catch(Exception ex)
      {        
        throw;
      }
    }

    private void cmdDeselectOne_Click(object sender, System.EventArgs e)
    {
      try
      {
        List<object> oList = new List<object>();
        foreach(object o in listBox2.SelectedItems)
        {
          oList.Add(o);
          listBox1.Items.Add(o);
        }

        for(int ii = listBox2.SelectedItems.Count - 1 ; ii >= 0 ; ii--)
          listBox2.Items.Remove(listBox2.SelectedItems[ii]);

        this.EnableButtons();

        foreach(object o in oList)
          this.OnItemDeselected(new ObjectEventArgs(o));

      }
      catch(Exception ex)
      {        
        throw;
      }
    }

    private void cmdDeselectAll_Click(object sender, System.EventArgs e)
    {
			try
			{
				List<object> list = new List<object>();
				foreach (object o in listBox2.Items)
					list.Add(o);

				listBox1.Items.AddRange(listBox2.Items);
				listBox2.Items.Clear();
				this.EnableButtons();

				//foreach (object o in listBox1.Items)
				//  this.OnItemDeselected(new ObjectEventArgs(o));

				this.OnDeselectAll(new ObjectListEventArgs(list));

			}
			catch (Exception ex)
			{
				throw;
			}

    }

    private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
    {
      this.EnableButtons();
			OnItemHighlighted(new ObjectEventArgs(listBox1.SelectedItem));
    }

    private void listBox2_SelectedIndexChanged(object sender, System.EventArgs e)
    {
      this.EnableButtons();
			OnItemHighlighted(new ObjectEventArgs(listBox2.SelectedItem));
    }

		private void listBox1_Enter(object sender, System.EventArgs e)
		{
			this.List1Highlighted = true;
		}

		private void listBox2_Enter(object sender, System.EventArgs e)
		{
			this.List1Highlighted = false;
		}

		#endregion

	}

	#region EventArgs

	public class ObjectEventArgs : System.EventArgs
  {
    private object _item = null;

    protected internal ObjectEventArgs(object item)
    {
      _item = item;
    }

    public object Item
    {
      get { return _item; }
    }

  }

	public class ObjectListEventArgs : System.EventArgs
	{
		private IEnumerable<object> _objectList = null;

		protected internal ObjectListEventArgs(IEnumerable<object> objectList)
		{
			_objectList = objectList;
		}

		public IEnumerable<object> ObjectList
		{
			get { return _objectList; }
		}

	}

	#endregion

}
